package com.yazi.mxz.common.service.impl;

import java.util.List;

import javax.annotation.Resource;

import com.myframework.smhj.common.exception.MyEntityNotExistsException;
import com.myframework.smhj.common.exception.MyException;
import com.myframework.smhj.common.exception.MyIllegalArgumentException;
import com.myframework.smhj.common.exception.MyNoPermissionException;
import com.myframework.smhj.common.tool.DateUtil;
import com.myframework.smhj.hibernate.dao.BasicService;
import com.myframework.smhj.hibernate.dao.Dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.yazi.mxz.common.ComSetting;
import com.yazi.mxz.common.client.ActFactory;
import com.yazi.mxz.common.db.dao.GoodsGiftDao;
import com.yazi.mxz.common.db.dao.GoodsPromoteDao;
import com.yazi.mxz.common.db.dao.StoreGoodsDao;
import com.yazi.mxz.common.entity.ValueFactory;
import com.yazi.mxz.common.entity.beans.GoodsGift;
import com.yazi.mxz.common.entity.beans.GoodsPromote;
import com.yazi.mxz.common.entity.beans.GoodsPromoteId;
import com.yazi.mxz.common.entity.beans.Store;
import com.yazi.mxz.common.entity.beans.StoreGoods;
import com.yazi.mxz.common.entity.enums.GoodsGiftType;
import com.yazi.mxz.common.entity.enums.GoodsPromoteStatus;
import com.yazi.mxz.common.entity.enums.GoodsPromoteType;
import com.yazi.mxz.common.entity.enums.SettingId;
import com.yazi.mxz.common.service.GoodsPromoteService;

@Service("goodsPromoteService")
public class GoodsPromoteServiceImpl extends BasicService<GoodsPromote> implements GoodsPromoteService {
	private static Logger log = LoggerFactory.getLogger(GoodsPromoteServiceImpl.class);

	@Resource
	GoodsPromoteDao goodsPromoteDao;
	@Resource
	StoreGoodsDao storeGoodsDao;
	@Resource
	GoodsGiftDao goodsGiftDao;

	@Override
	protected Dao<GoodsPromote> getDao() {
		return goodsPromoteDao;
	}
	
	@Override
	public int endByTime(GoodsPromoteType type) {
		int count = goodsPromoteDao.endByTime(type);
		log.debug("endByTime: type={},count={}", type, count);
		switch (type) {
		case ONLINE_DISCOUNT:
			storeGoodsDao.false4AtDiscount();
			break;
		case ONLINE_GIFT:
			storeGoodsDao.false4AtGift();
			break;
		case LOCAL_DISCOUNT:
			storeGoodsDao.false4AtDiscountLocal();
			break;
		case LOCAL_GIFT:
			storeGoodsDao.false4AtGiftLocal();
			break;
		}
		return count;
	}

	@Override
	public int startByTime(GoodsPromoteType type) {
		int count = goodsPromoteDao.startByTime(type);
		log.debug("startByTime: type={},count={}", type, count);
		switch (type) {
		case ONLINE_DISCOUNT:
			storeGoodsDao.true4AtDiscount();
			break;
		case ONLINE_GIFT:
			storeGoodsDao.true4AtGift();
			break;
		case LOCAL_DISCOUNT:
			storeGoodsDao.true4AtDiscountLocal();
			break;
		case LOCAL_GIFT:
			storeGoodsDao.true4AtGiftLocal();
			break;
		
		}
		return count;
	}

	@Override
	public GoodsPromote oneNextStart() {
		GoodsPromote goodsPromote = goodsPromoteDao.oneNextStart();
		log.debug("oneNextStart：{}",
				null == goodsPromote ? "None"
						: DateUtil.getDateTimeStr(goodsPromote.getStartTime()));
		return goodsPromote;
	}

	@Override
	public GoodsPromote oneNextEnd() {
		GoodsPromote goodsPromote = goodsPromoteDao.oneNextEnd();
		log.debug("oneNextEnd：{}",
				null == goodsPromote ? "None" : DateUtil.getDateTimeStr(goodsPromote.getEndTime()));
		return goodsPromote;
	}

	@Override
	public GoodsPromote addOrEditByStore(Store store, GoodsPromote goodsPromote, List<GoodsGift> gifts) throws MyException {
		
		StoreGoods destStoreGoods = storeGoodsDao.get(goodsPromote.getId().getStoreGoodsId());
		if (!destStoreGoods.getStore().equals(store)) {
			throw new MyNoPermissionException();
		}

		GoodsPromote destGoodsPromote = goodsPromoteDao.get(goodsPromote.getId());
		
		if (null == destGoodsPromote) {// 添加
			
			log.debug("addOrModifyByStore->add：storeGoodsId={},type={}", 
					goodsPromote.getId().getStoreGoodsId(),goodsPromote.getId().getType());

			ValueFactory.validate(goodsPromote);
			goodsPromote.setStatus(GoodsPromoteStatus.NOSTART.ordinal());
			goodsPromote.setUpdateTime(DateUtil.getTimeStamp());
			destGoodsPromote = goodsPromoteDao.persist(goodsPromote);

			// 赠品处理
			if (null != gifts) {
				
				GoodsGiftType giftType = null;
				int type = destGoodsPromote.getId().getType().intValue();
				if (type == GoodsPromoteType.ONLINE_GIFT.ordinal()) {
					giftType = GoodsGiftType.ONLINE;
				} else if (type == GoodsPromoteType.LOCAL_GIFT.ordinal()) {
					giftType = GoodsGiftType.LOCAL;
				} else {
					throw new MyException("商品促销类型有误");
				}
				
				// 添加绑定赠送商品
				setGiftsByStore(store, destGoodsPromote.getId().getStoreGoodsId(), giftType, gifts);
			}
			
		} else {// 修改
			
			log.debug("addOrModifyByStore->modify：storeGoodsId={},type={}", 
					goodsPromote.getId().getStoreGoodsId(),goodsPromote.getId().getType());

			ValueFactory.combine(goodsPromote, destGoodsPromote);
			destGoodsPromote.setStatus(GoodsPromoteStatus.NOSTART.ordinal());
			destGoodsPromote.setUpdateTime(DateUtil.getTimeStamp());
			goodsPromoteDao.merge(destGoodsPromote);

			// 赠品处理
			if (null != gifts) {
				
				GoodsGiftType giftType = null;
				int type = destGoodsPromote.getId().getType().intValue();
				if (type == GoodsPromoteType.ONLINE_GIFT.ordinal()) {
					giftType = GoodsGiftType.ONLINE;
				} else if (type == GoodsPromoteType.LOCAL_GIFT.ordinal()) {
					giftType = GoodsGiftType.LOCAL;
				} else {
					throw new MyException("商品促销类型有误");
				}
				
				Long storeGoodsId = destGoodsPromote.getId().getStoreGoodsId();
				// 删除原有赠送品
				goodsGiftDao.deleteBySellId(storeGoodsId, giftType);
				// 添加绑定赠送商品
				setGiftsByStore(store, storeGoodsId, giftType, gifts);
			}
		}
		// 更新对应的商品信息中的促销状态
		modifyStoreGoodsStatus(destGoodsPromote.getId());
		// 触发状态更新任务
		ActFactory.actGoodsPromnoteJob(destGoodsPromote);
		return destGoodsPromote;
	}

	@Override
	public void removeByStore(Store store, GoodsPromoteId goodsPromoteId) throws MyException {
		log.debug("removeByStore: storeId={},storeGoodsId={},type={}", 
				new Object[]{store.getStoreId(), goodsPromoteId.getStoreGoodsId(), goodsPromoteId.getType()});
		
		removeByStore_(store, goodsPromoteId);
	}

	@Override
	public void editStatusByStore(Store store, GoodsPromoteId goodsPromoteId,
			GoodsPromoteStatus status) throws MyException {
		log.debug("modifyStatusByStore: storeId={},storeGoodsId={},type={}", 
				new Object[]{store.getStoreId(), goodsPromoteId.getStoreGoodsId(), goodsPromoteId.getType()});

		// 只能取消和重置（未开始）
		if (status != GoodsPromoteStatus.CANCELLED && status != GoodsPromoteStatus.NOSTART) {
			throw new MyNoPermissionException();
		}

		StoreGoods storeGoods = storeGoodsDao.get(goodsPromoteId.getStoreGoodsId());
		if (null == storeGoods) {
			throw new MyEntityNotExistsException();
		}
		if (!storeGoods.getStore().equals(store)) {
			throw new MyNoPermissionException();
		}

		GoodsPromote goodsPromote = goodsPromoteDao.get(goodsPromoteId);
		if (null == goodsPromote) {
			throw new MyEntityNotExistsException();
		}

		modifyStatus(goodsPromoteId, status);

		// 触发状态更新任务
		if (status == GoodsPromoteStatus.NOSTART) {
			ActFactory.actGoodsPromnoteJob(goodsPromote);
		}
	}

	@Override
	public void removeByStore(Store store, List<GoodsPromoteId> goodsPromoteIds) throws MyException {
		log.debug("removeByStore：storeId={},size={}", store.getStoreId(), goodsPromoteIds.size());
		for (GoodsPromoteId goodsPromoteId : goodsPromoteIds) {
			removeByStore_(store, goodsPromoteId);
		}
	}

	/**
	 * 删除店铺的商品促销
	 * 
	 * @param store
	 * @param goodsPromoteId
	 */
	private void removeByStore_(Store store, GoodsPromoteId goodsPromoteId) throws MyException {
		
		
		GoodsPromote goodsPromote = goodsPromoteDao.get(goodsPromoteId);
		if (null == goodsPromote) {
			return;
		}
		
		StoreGoods storeGoods = storeGoodsDao.get(goodsPromoteId.getStoreGoodsId());
		if (!storeGoods.getStore().equals(store)) {
			return;
		}
		
		// 删除赠送品
		if (goodsPromote.getId().getType() == GoodsPromoteType.ONLINE_GIFT.ordinal()) {
			goodsGiftDao.deleteBySellId(goodsPromote.getId().getStoreGoodsId(), GoodsGiftType.ONLINE);
		} else if (goodsPromote.getId().getType() == GoodsPromoteType.LOCAL_GIFT.ordinal()) {
			goodsGiftDao.deleteBySellId(goodsPromote.getId().getStoreGoodsId(), GoodsGiftType.LOCAL);
		}
		
		modifyStoreGoodsStatus(goodsPromote.getId(), GoodsPromoteStatus.CANCELLED);
		
		goodsPromoteDao.delete(goodsPromote);
	}

	/**
	 * 根据促销活动状态，更新商品的对应状态
	 * 
	 * @param id
	 */
	private void modifyStoreGoodsStatus(GoodsPromoteId id) {
		modifyStatus(id, null);
	}

	/**
	 * 更新促销活动状态及相应商品的对应状态
	 * 
	 * @param id
	 * @param destStatus
	 */
	private void modifyStoreGoodsStatus(GoodsPromoteId id, GoodsPromoteStatus destStatus) {
		modifyStatus(id, destStatus);
	}

	/**
	 * 更新状态
	 * 
	 * @param id
	 * @param destStatus
	 */
	private void modifyStatus(GoodsPromoteId id, GoodsPromoteStatus destStatus) {
		
		GoodsPromote promote = goodsPromoteDao.get(id);
		if (null == destStatus) {
			destStatus = GoodsPromoteStatus.values()[promote.getStatus()];
		} else {
			promote.setStatus(destStatus.ordinal());
			goodsPromoteDao.merge(promote);
		}

		GoodsPromoteType type = GoodsPromoteType.values()[id.getType()];
		StoreGoods storeGoods = storeGoodsDao.get(id.getStoreGoodsId());
		switch (destStatus) {
		case CANCELLED:
		case NOSTART:
		case ENDED:
			if (type == GoodsPromoteType.ONLINE_GIFT) {
				storeGoods.setAtGift(false);
			} else if (type == GoodsPromoteType.ONLINE_DISCOUNT) {
				storeGoods.setAtDiscount(false);
			} else if (type == GoodsPromoteType.LOCAL_GIFT) {
				storeGoods.setAtGiftLocal(false);
			} else if (type == GoodsPromoteType.LOCAL_DISCOUNT) {
				storeGoods.setAtDiscountLocal(false);
			}
			break;
		case SALING:
			if (type == GoodsPromoteType.ONLINE_GIFT) {
				storeGoods.setAtGift(true);
			} else if (type == GoodsPromoteType.ONLINE_DISCOUNT) {
				storeGoods.setAtDiscount(true);
			} else if (type == GoodsPromoteType.LOCAL_GIFT) {
				storeGoods.setAtGiftLocal(true);
			} else if (type == GoodsPromoteType.LOCAL_DISCOUNT) {
				storeGoods.setAtDiscountLocal(true);
			}
			break;
		}
		storeGoodsDao.merge(storeGoods);
	}

	/**
	 * 给店铺的商品绑定赠送品
	 * 
	 * @param store
	 * @param storeGoodsId
	 * @param gifts
	 */
	private void setGiftsByStore(Store store, long storeGoodsId, GoodsGiftType giftType, List<GoodsGift> gifts) throws MyException {

		// 赠送品种上限
		int count = ComSetting.getInteger(SettingId.GOODS_GIFT_AMOUNT);
		if (gifts.size() > count) {
			throw new MyIllegalArgumentException("最多可赠送" + count + "种商品");
		}
		// 检查赠送商品是否属于店铺
		for (GoodsGift gift : gifts) {
			if (null == gift.getId() || null == gift.getId().getGiftId()) {
				continue;
			}
			StoreGoods storeGoodsByGiftId = storeGoodsDao.get(gift.getId().getGiftId());
			// 只能是当前店铺商品,否则忽略
			if (null != storeGoodsByGiftId && storeGoodsByGiftId.getStore().equals(store)) {
				gift.getId().setSellId(storeGoodsId);
				gift.getId().setGiftId(storeGoodsByGiftId.getStoreGoodsId());
				gift.getId().setType(giftType.ordinal());
				goodsGiftDao.persist(gift);
				// TODO 赠品库存检查
			}
		}

	}

}
